type
status
date
slug
summary
tags
category
icon
password
😀
大家好!在过去的几天里,我制作了一个名为dnspeep的小工具,它可以让你看到你的电脑正在进行哪些 DNS查询,以及它收到的响应。它目前大约有 250 行 Rust 代码。 我将讨论如何尝试它,它的用途,我为什么制作它,以及我在编写它时遇到的一些问题。

📝 dnspeep:窥探DNS查询的工具

如何尝试

我构建了一些二进制文件,以便您可以快速试用它。
对于 Linux(x86):
对于 Mac:
它需要以 root 身份运行,因为它需要访问您的计算机发送的所有 DNS 数据包。 这与 tcpdump 需要以 root 身份运行的原因相同——它使用 libpcap,这是 tcpdump 使用的同一个库。
您也可以在 https://github.com/jvns/dnspeep 阅读源代码并自己构建它,如果您不想只是下载二进制文件并以 root 身份运行它们 :)。

输出是什么样的

以下是输出的样子。 每一行都是一个 DNS 查询和响应。
这些查询来自我在浏览器中访问 neopets.com,而bolt.dropbox.com 查询是因为我正在运行 Dropbox 代理,我猜它会不时地在后台打电话回家,因为它需要同步。

为什么还要制作另一个 DNS 工具?

我制作这个工具是因为我认为当你对 DNS 不太了解时,它会显得非常神秘!
您的浏览器(以及您计算机上的其他软件)一直在进行 DNS 查询,我认为当您能够实际看到查询和响应时,它会让它看起来更加“真实”。
我还编写了这个工具用作调试工具。 我认为“这是一个 DNS 问题吗?”这个问题比它应该的更难回答——我的印象是,当试图检查问题是否是由 DNS 引起时,人们通常会使用试错法或猜测,而不是仅仅查看他们的计算机正在获得的 DNS 响应。

您可以看到哪些软件“秘密地”使用互联网

我喜欢这个工具的一件事是它让我了解我的计算机上的哪些程序正在使用互联网! 例如,我发现我的计算机上的某些东西出于某种原因会不时向 ping.manjaro.org 发出请求,可能是为了检查我是否连接到互联网。
我的一个朋友实际上使用这个工具发现他的电脑上安装了一些他忘记卸载的旧工作中的公司监控软件,所以你甚至可能会找到一些你想要删除的东西。

如果你不习惯 tcpdump,它会让人困惑

当我试图向人们展示他们的计算机正在进行的 DNS 查询时,我的第一个本能是说“好吧,使用 tcpdump”! tcpdump 确实解析 DNS 数据包!
例如,以下是 incoming.telemetry.mozilla.org. 的 DNS 查询的样子:
这绝对是可以学习阅读的,例如让我们分解一下查询:
  • A? 表示它是 A 类型的 DNS 查询
  • 56271 是 DNS 查询的 ID
  • 192.168.1.181.42281 是源 IP/端口
  • 192.168.1.1.53 是目标 IP/端口
  • (48) 是 DNS 数据包的长度
而在响应中分解如下:
  • 3/0/0 是响应中的记录数:3 个答案,0 个权威,0 个附加。 我认为 tcpdump 将永远只打印出答案响应。
  • 56271 是响应 ID,它与查询的 ID 匹配。 这就是您如何判断它是对上一行请求的响应。
我认为使这种格式最难以处理的是(作为一个只想查看一些 DNS 流量的人),您必须手动匹配请求和响应,而且它们并不总是在相邻的行上。 那是计算机擅长的!
所以我决定编写一个小程序 (dnspeep),它会进行这种匹配,并删除一些我认为是无关紧要的信息。

我在编写它时遇到的问题

在编写这个程序时,我遇到了一些问题。
  • 我不得不修补 pcap crate 以使其在 Mac OS 上与 Tokio 正常工作(此更改)。 这是一个花了几个小时才弄清楚,1 行代码就修复的错误 :)
  • 不同的 Linux 发行版似乎有不同版本的 libpcap.so,所以我无法轻松分发动态链接 libpcap 的二进制文件(您可以看到其他人在这里遇到了同样的问题)。 所以我决定在 Linux 上将 libpcap 静态编译到该工具中。 我仍然不知道如何在 Rust 中正确地做到这一点,但我通过将 libpcap.a 文件复制到 target/release/deps 然后运行 cargo build 来使其工作。
  • 我使用的 dns_parser crate 不支持所有 DNS 查询类型,只支持最常见的类型。 我可能需要切换到另一个 crate 来解析 DNS 数据包,但我还没有找到合适的。
  • 因为 pcap 接口只提供原始字节(包括以太网帧),所以我需要编写代码来确定要从开头剥离多少字节才能获得数据包的 IP 标头。 我很确定我仍然遗漏了一些情况。
我很难给它命名,因为已经有很多 DNS 工具了(dnsspy!dnssnoop!dnssniff!dnswatch!)。 我基本上只是查看了“spy”的每一个同义词,然后选择了一个看起来很有趣且还没有附加 DNS 工具的同义词。
这个程序不做的一件事是告诉你哪个进程进行了 DNS 查询,我发现有一个叫做 dnssnoop 的工具可以做到这一点。 它使用 eBPF,看起来很酷,但我还没有尝试过。

可能仍然有很多错误

我只在 Linux 和 Mac 上简要测试过它,我已经知道至少有一个错误(由于不支持足够的 DNS 查询类型),所以请报告您遇到的问题!
但是这些错误并不危险——因为 libpcap 接口是只读的,最糟糕的事情就是它会得到一些它不理解的输入并打印出错误或崩溃。

编写小型教育工具很有趣

我最近一直在享受编写小型教育性 DNS 工具的乐趣。
到目前为止,我已经制作了:
  • 这个工具 (dnspeep)
从历史上看,我主要试图解释现有的工具(如 digtcpdump),而不是编写我自己的工具,但我经常发现这些工具的输出令人困惑,所以我对制作更友好的方式来查看相同的信息感兴趣,以便每个人都能理解他们的计算机正在进行哪些 DNS 查询,而不仅仅是 tcpdump 向导 :)。

📎 参考文章

💡
有关dnspeep使用上的问题,欢迎您在底部评论区留言,一起交流~
如何使用 ChatGPT 原理学会一切知识一步到位:用 n8n 和 Zapier 实现 Ghost 文章自动推送到 Telegram 并同步到 Twitter
Loading...